<ui:composition template="/WEB-INF/templates/showcase.xhtml"
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:o="http://omnifaces.org/ui"
>
	<ui:define name="description">
		<p>
			By default, when an exception occurs during a JSF ajax request, the enduser would not get any form of feedback
			if the action was successfully performed or not. In Mojarra, only when the project stage is set to 
			<code>Development</code>, the enduser would see a bare JavaScript alert with only the exception type and message.
			It would make sense if exceptions during ajax requests are handled the same way as exceptions during synchronous 
			requests, which is utilizing the standard Servlet API <code>&lt;error-page&gt;</code> mechanisms in <code>web.xml</code>.
		</p>
		<p>
			This <code>FullAjaxExceptionHandler</code> enables you to show the full error page in its entirety to the 
			enduser in case of exceptions during ajax requests. This exception handler will parse the <code>web.xml</code> 
			and <code>web-fragment.xml</code> files to find the error page locations of the HTTP error code 500 and all 
			declared specific exception types.
		</p>
		
		<h3>Installation</h3>
		<p>
			This handler must be registered by a factory as follows in <code>faces-config.xml</code> in order to get it to run:
		</p>
		<pre class="prettyprint"><code class="lang-xml">
&lt;factory&gt;
    &lt;exception-handler-factory&gt;org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory&lt;/exception-handler-factory&gt;
&lt;/factory&gt;
		</code></pre>

		<h3>Demo</h3>
		<p>
			The buttons in the below demo will each purposefully throw an exception. You'll see that an error page template
			is presented regardless of if it's an ajax request or not. Also, if you wait #{session.maxInactiveInterval / 60} 
			minutes or manually delete the <code>JSESSIONID</code> cookie or press the below "Invalidate session" button 
			and then click any of the buttons on the demo, then you'll get a view expired exception which will also end up 
			in a specific error page.
		</p>
		<p>
			<input type="button" value="Invalidate session"
				onclick="$.get('#{request.contextPath}/invalidatesession?#{now.time}', alert('Session invalidated!'))" />
		</p>
		<p>
			This exception handler is also  
			<a href="http://code.google.com/p/omnifaces-showcase/source/browse/WebContent/WEB-INF/faces-config.xml">configured</a>
			on this showcase web application. The following error pages are been
			<a href="http://code.google.com/p/omnifaces-showcase/source/browse/WebContent/WEB-INF/web.xml">configured</a>
			on this showcase web application:
		</p>
		<pre class="prettyprint"><code class="lang-xml">
&lt;error-page&gt;
    &lt;exception-type&gt;javax.faces.application.ViewExpiredException&lt;/exception-type&gt;
    &lt;location&gt;/WEB-INF/errorpages/expired.xhtml&lt;/location&gt;
&lt;/error-page&gt;
&lt;error-page&gt;
    &lt;exception-type&gt;java.sql.SQLException&lt;/exception-type&gt;
    &lt;location&gt;/WEB-INF/errorpages/database.xhtml&lt;/location&gt;
&lt;/error-page&gt;
&lt;error-page&gt;
    &lt;exception-type&gt;java.lang.RuntimeException&lt;/exception-type&gt;
    &lt;location&gt;/WEB-INF/errorpages/bug.xhtml&lt;/location&gt;
&lt;/error-page&gt;
		</code></pre>
		
		<p>
			Please note that the error page <strong>must</strong> be a valid Facelets page! JSP is not supported.
		</p>
		
		<h3>Normal requests</h3>
		<p>
			Note that the <code>FullAjaxExceptionHandler</code> does not deal with normal (non-ajax) requests at all.
			To properly handle JSF and EL exceptions on normal requests as well, you need an additional
			<h:link outcome="/filters/FacesExceptionFilter"><code>FacesExceptionFilter</code></h:link>.
			This will extract the root cause from a wrapped <code>FacesException</code> and <code>ELException</code>
			before delegating the <code>ServletException</code> further to the container (the container will namely use
			the first root cause of <code>ServletException</code> to match an error page by exception in web.xml). 
		</p>
	</ui:define>

	<ui:define name="demo">
		<h:form>
			<h:commandButton value="throw runtime exception on ajax request" action="#{exceptionBean.throwRuntimeException}">
				<f:ajax execute="@form" render="@form" />
			</h:commandButton>
		</h:form>
		<h:form>
			<h:commandButton value="throw runtime exception on normal request" action="#{exceptionBean.throwRuntimeException}" />
		</h:form>
		<h:form>
			<h:commandButton value="throw SQL exception on ajax request" action="#{exceptionBean.throwSQLException}">
				<f:ajax execute="@form" render="@form" />
			</h:commandButton>
		</h:form>
		<h:form>
			<h:commandButton value="throw SQL exception on normal request" action="#{exceptionBean.throwSQLException}" />
		</h:form>
	</ui:define>		
</ui:composition>